#pragma once

#include <iostream>
#include <sys/epoll.h>
#include <cstring>
#include "Log.hpp"
#include "Nocopy.hpp"

// 继承Nocopy类 实现禁止拷贝构造和拷贝赋值的功能
class Epoller : public Nocopy{
    static const int size = 128;

public:
    Epoller()
    :_timeout(2000)
    {
        // 创建epoll模型 返回值是这个模型所在的文件描述符
        _epfd = epoll_create(size);
        if(_epfd == -1){
            mylog(Error, "epoll create error..., strerror: %s", strerror(errno));
        }
        else{
            mylog(INFO, "epoll create success, epfd is %d", _epfd);
        }
    }

    int EpollerWait(struct epoll_event events[], const int &maxnum){
        // 根据timeout间隔时间进行等待，返回值n是就绪的fd个数
        int n = epoll_wait(_epfd, events, maxnum, _timeout);      
        return n;
    }

    void EpollerUpDate(const int &oper, const int &fd, const uint32_t &event){
        int n = 0;
        if (oper == EPOLL_CTL_DEL){
            n = epoll_ctl(_epfd, oper, fd, nullptr);
            if (n != 0){
                mylog(Error, "epoll delete error..., fd is %d", fd);
                return;
            }
        }
        // oper == EPOLL_CTL_ADD/EPOLL_CTL_MOD
        else{
            // 设置要修改/增加的fd对应的事件结构体
            struct epoll_event events;
            events.events = event;
            events.data.fd = fd;

            n = epoll_ctl(_epfd, oper, fd, &events);
            if (n != 0){
                mylog(Error, "epoll add/mod error..., fd is %d", fd);
                return;
            }
        }
    }

    ~Epoller()
    {
        if(_epfd >= 0){
            close(_epfd);
        }
    }
private:
    int _epfd;
    int _timeout;
};